package com.example.onlinemonitoring.comCenter;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import com.example.onlinemonitoring.Util.CRC16;
import com.example.onlinemonitoring.Util.CommPortManager;
import com.example.onlinemonitoring.Util.IEEE754Utils;
import com.example.onlinemonitoring.Util.LanguageManager;
import com.example.onlinemonitoring.Util.tem.SensorAbstractBaseService;
import com.example.onlinemonitoring.controller.indexController.rescount;
import com.example.onlinemonitoring.model.Appdevice;
import com.example.onlinemonitoring.model.Dlqjcsensor;
import com.example.onlinemonitoring.model.Jdqconfig;
import com.example.onlinemonitoring.model.Tgsensor;
import com.example.onlinemonitoring.model.common.MyResult;
import com.example.onlinemonitoring.model.common.sensor;
import com.example.onlinemonitoring.serviceImpl.AppdeviceServiceImpl;
import com.example.onlinemonitoring.serviceImpl.JdqconfigServiceImpl;
import com.example.onlinemonitoring.serviceImpl.TgsensorServiceImpl;

import tk.mybatis.mapper.entity.Example;

/**
 * 继电器输出
 */
@Service("jdqCom")
@Scope("prototype")
public class JdqCom extends CommPortManager {
    @Autowired
    BeanFactory beanFactory;
    @Autowired
    private JdqconfigServiceImpl jdqserviceimpl;
    @Autowired
    AppdeviceServiceImpl appdeviceImpl;
    @Autowired
    JdqconfigServiceImpl jdqconfigserviceimpl;
    @Autowired
    LanguageManager languageManager;

    @Async("threadPool")
    public void startSendThread(Appdevice Appdevice) throws Exception {
        checkType = "crc16";
        issend.put(Thread.currentThread().getId(), true);
        int timersp = (int) Math.round(Appdevice.getTimersp() * 1000);
        while (issend.get(Thread.currentThread().getId()) != null) {
            if (isrun) {
                try {
                    PreSend();// 准备发送
                } catch (Exception e) {
                    e.printStackTrace();
                }

            } else if (rescode != 0) {
                setText(resmsg[rescode]);
            }
            Thread.sleep(timersp);
        }
    }

    public void PreSend() {

        List<Appdevice> devicelist = new ArrayList<>();
        Example example = new Example(Appdevice.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("isshow", 1);
        devicelist = appdeviceImpl.getList(example).getData();
        if (devicelist == null) {
            setText("设备列表为空或被隐藏\r\n");
            return;
        }

        Integer totalwarncount = 0, totalalarmcount = 0, totalabnormalcount = 0;
        Map<String, List<Boolean>> map = new HashMap<>();
        for (int j = 0; j < devicelist.size(); j++) {
            Appdevice record = devicelist.get(j);
            if (!devicelist.get(j).getSimple().contains("61850") && !devicelist.get(j).getType().equals("转发")) {
                @SuppressWarnings("unchecked")
                SensorAbstractBaseService<sensor, sensor> service = (SensorAbstractBaseService<sensor, sensor>) beanFactory
                        .getBean(devicelist.get(j).getSimple() + "ServiceImpl");
                int warncount = service.getWarnCount(record.getStationid(), record.getDevicegroup());
                int alarmcount = service.getAlarmCount(record.getStationid(), record.getDevicegroup());
                int abnormalcount = service.getAbnormalCount(record.getStationid(), record.getDevicegroup());
                List<Boolean> lb = new ArrayList<>();
                lb.add(warncount != 0);
                lb.add(alarmcount != 0);
                lb.add(abnormalcount != 0);
                map.put(record.getStationid() + "-" + record.getDevicegroup() + "-" + record.getSimple(), lb);
                totalwarncount += warncount;
                totalalarmcount += alarmcount;
                totalabnormalcount += abnormalcount;
            }
        }
        List<Boolean> lb = new ArrayList<>();
        lb.add(totalwarncount != 0);
        lb.add(totalalarmcount != 0);
        lb.add(totalabnormalcount != 0);
        map.put("1-1-all", lb);
        String s = "";
        String route[] = new String[] { "0", "0", "0", "0", "0", "0", "0", "0" };
        Example example2 = new Example(Jdqconfig.class);
        Example.Criteria criteria2 = example2.createCriteria();
        criteria2.andEqualTo("stationid", ad.getStationid());
        criteria2.andEqualTo("devicegroup", ad.getDevicegroup());
        devicelist = appdeviceImpl.getList(example2).getData();
        List<Jdqconfig> jdqlist = jdqserviceimpl.selectByExample(example2);
        List<List<Jdqconfig>> filteredList = new ArrayList<>();
        for (int i = 0; i < 8; i++) {
            filteredList.add(new ArrayList<>());
        }

        for (Jdqconfig jdq : jdqlist) {
            int dbroute = jdq.getDbroute(); // 获取继电器路
            if (dbroute < 1 || dbroute > 8) {
                setText(jdq.getBindname() + languageManager.getLan().getRelayDatabaseCorrupted() + "\r\n");
                return;
            }
            int signal = jdq.getBindsignal(); // 获取继电器信号索引
            if (signal < 1 || signal > 3) {
                setText(jdq.getBindname() + languageManager.getLan().getRelayDatabaseCorrupted() + "\r\n");
                return;
            }
            filteredList.get(dbroute - 1).add(jdq);
        }

        for (int i = 0; i < filteredList.size(); i++) {
            boolean isAlm = false;
            for (int j = 0; j < filteredList.get(i).size(); j++) {
                Jdqconfig almjdq = filteredList.get(i).get(j);
                if (((almjdq.getDeviceaddr() == null || almjdq.getDeviceaddr() == -1)
                        && (almjdq.getPointaddr() == null || almjdq.getPointaddr() == -1))
                        || almjdq.getSimplename().equals("all")) {
                    try {
                        boolean isjdqalm = map
                                .get(almjdq.getBindstationid() + "-" + almjdq.getBinddevicegroup() + "-"
                                        + almjdq.getSimplename())
                                .get(almjdq.getBindsignal() - 1);
                        isAlm = isAlm || isjdqalm;
                        if (isAlm) {
                            route[i] = "1";
                            break;
                        }
                    } catch (Exception e) {
                        setText(almjdq.getBindstationid() + "-" + almjdq.getBinddevicegroup() + "-"
                                + almjdq.getSimplename() + languageManager.getLan().getDeviceNotFound());
                    }
                } else {// 精确到地址或者监测点
                    @SuppressWarnings("unchecked")
                    SensorAbstractBaseService<sensor, sensor> service = (SensorAbstractBaseService<sensor, sensor>) beanFactory
                            .getBean(almjdq.getSimplename().split("-")[0] + "ServiceImpl");
                    if (almjdq.getBindsignal() == 1) {
                        int warncount = service.getWarnCount(almjdq.getBindstationid(), almjdq.getBinddevicegroup(),
                                almjdq.getDeviceaddr(), almjdq.getPointaddr());
                        isAlm = isAlm || warncount != 0;
                    }
                    if (almjdq.getBindsignal() == 2) {
                        int alarmcount = service.getAlarmCount(almjdq.getBindstationid(), almjdq.getBinddevicegroup(),
                                almjdq.getDeviceaddr(), almjdq.getPointaddr());
                        isAlm = isAlm || alarmcount != 0;
                    }
                    if (almjdq.getBindsignal() == 3) {
                        int abnormalcount = service.getAbnormalCount(almjdq.getBindstationid(),
                                almjdq.getBinddevicegroup(),
                                almjdq.getDeviceaddr(), almjdq.getPointaddr());
                        isAlm = isAlm || abnormalcount != 0;
                    }
                    if (isAlm) {
                        route[i] = "1";
                        break;
                    }
                }
            }
        }
        int decimalValue = Integer
                .parseInt(route[7] + route[6] + route[5] + route[4] + route[3] + route[2] + route[1] + route[0], 2);
        s += ad.getCmd();
        s += String.format("%04X", decimalValue);
        s += CRC16.calcCrc16(s);
        Send(s);
    }
}
